#include <stdio.h>
#include <stdlib.h>
#include <Spectrum.h>
#include <Database.h>
#include <cleavage.h>
#include <clUtil.h>
#include <init.h>
#include <string>
#include <exception>

using namespace std;
using namespace clUtil;

int main(int argc, char** argv)
{
  bool proteinsDone = false;

  const char* files[] = {
                          "kernels/main.cl"
                        };

  init(argc, argv);

  Device::InitializeDevices(files, 
                            sizeof(files) / sizeof(const char*), 
                            NULL, 
                            "-Ikernels "
                            //"-g -O0"
                            //"-cl-finite-math-only " //optimizations...
                            //"-cl-mad-enable " //...
                            //"-cl-no-signed-zeros -cl-strict-aliasing " //...
                            );

  try
  {
    Database theDatabase(gProteinDatabase, cleavageTrypsin);
    
    vector< unique_ptr<Spectrum > > theSpectra;
       
    for(char* MSMSdataFile : gMSMSDataFiles)
    {
      unique_ptr<Spectrum> newSpec(new Spectrum(MSMSdataFile));
      theSpectra.push_back(move(newSpec));
    }
    
    do
    {
      proteinsDone = theDatabase.copyToDevices();
      fflush(stdout);
      
      //theDatabase.printPeptides();

      for(unsigned int curMSMS = 0; curMSMS < gMSMSDataFiles.size();curMSMS++)
      { 
        (theSpectra[curMSMS])->allocateDevices();

#if 0
        printf("Running on %s processing %s\n", 
               Device::GetCurrentDevice().getDeviceInfo().Name.c_str(), 
               gMSMSDataFiles[curMSMS]);
#endif

        (theSpectra[curMSMS])->processSpectrum(theDatabase);

        (theSpectra[curMSMS])->freeDevices();
      }
    }
    while(!proteinsDone);
    
    for(unsigned int curMSMS = 0; curMSMS < gMSMSDataFiles.size();curMSMS++)
    {
      string outputFileName = string(gMSMSDataFiles[curMSMS]) + ".pep";
      (theSpectra[curMSMS])->combineScores(theDatabase, outputFileName.c_str());
    }
    
    theSpectra.clear();
  } 
  catch(exception& err)
  {
    printf("%s\n", err.what());
    exit(1);
  }
  catch(clUtilException& err)
  {
    printf("%s\n", err.what());
    exit(1);
  }  
  fflush(stdout);
  
}
